#!/usr/bin/python

import string, sys, os, subprocess as sub

#encodes, deletes devices, and decodes
#main() has a list of the methods to use

class EncodeRun:
	def __init__(self,k,m,method,w,ps,buf):
		self.k = k
		self.m = m
		self.method = method
		self.w = w
		self.ps = ps
		self.buf = buf

#create all the runs: EncodeRun(k,m,method,w,ps,buffer)
encode_runs = []

er = EncodeRun(10,5,"cauchy_orig",7,2048,0)
encode_runs.append(er)
er = EncodeRun(10,5,"cauchy_orig",15,2048,0)
encode_runs.append(er)
er = EncodeRun(10,5,"cauchy_orig",17,2048,0)
encode_runs.append(er)
er = EncodeRun(10,5,"cauchy_orig",31,2048,0)
encode_runs.append(er)

er = EncodeRun(6,4,"reed_sol_van",8,0,0)
encode_runs.append(er)
er = EncodeRun(6,4,"reed_sol_van",16,0,0)
encode_runs.append(er)
er = EncodeRun(10,10,"reed_sol_van",32,0,0)
encode_runs.append(er)

er = EncodeRun(10,2,"reed_sol_r6_op",8,0,0)
encode_runs.append(er)
er = EncodeRun(10,2,"reed_sol_r6_op",8,0,1024000)
encode_runs.append(er)
er = EncodeRun(10,2,"reed_sol_r6_op",16,0,1024000)
encode_runs.append(er)
er = EncodeRun(16,2,"reed_sol_r6_op",32,0,1024000)
encode_runs.append(er)

er = EncodeRun(10,5,"cauchy_orig",8,2048,0)
encode_runs.append(er)
er = EncodeRun(10,5,"cauchy_orig",8,2048,1024000)
encode_runs.append(er)

#liber8tion
er = EncodeRun(10,5,"cauchy_good",8,2048,0)
encode_runs.append(er)
er = EncodeRun(10,5,"cauchy_good",8,2048,1024000)
encode_runs.append(er)

#liberation
er = EncodeRun(7,2,"r6_min_density",7,2048,0)
encode_runs.append(er)
er = EncodeRun(7,2,"r6_min_density",7,2048,1024000)
encode_runs.append(er)

#blaum-roth
er = EncodeRun(10,2,"r6_min_density",10,2048,0)
encode_runs.append(er)
er = EncodeRun(10,2,"r6_min_density",10,2048,1024000)
encode_runs.append(er)

er = EncodeRun(6,2,"gen_rdp",6,2048,0)
encode_runs.append(er)
er = EncodeRun(6,2,"gen_rdp",6,2048,1024000)
encode_runs.append(er)

er = EncodeRun(6,2,"gen_evenodd",6,2048,0)
encode_runs.append(er)
er = EncodeRun(6,2,"gen_evenodd",6,2048,1024000)
encode_runs.append(er)

def main():

	if len(sys.argv) < 2:
		sys.exit("Usage: " + sys.argv[0] + " filename")
	else:
		filename = sys.argv[1]

	num_total = 0
	num_good = 0
	num_failed = 0

	for er in encode_runs:
		
		method = er.method
		k = er.k
		m = er.m
		w = er.w
		ps = er.ps
		buf = er.buf

		#delete the old coding folder
		os.system("rm -rf ./Coding")
		
		#encode
		cmd_encode = "./encoder " + filename + " " + str(k) + " " + str(m) + " " + method + " " + str(w) + " " + str(ps) + " " + str(buf)
		print(cmd_encode)
		p = sub.Popen(cmd_encode,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
		output, errors = p.communicate()
		if errors != "":
			print("     " + errors)
		
		#delete m devices, first delete data, then coding (to simulate the worst case)
		if m >= k:
			k_drives_to_delete = k
			m_drives_to_delete = m-k	
		else:
			k_drives_to_delete = m
			m_drives_to_delete = 0

		#delete data drives
		for i in xrange(0,k_drives_to_delete):
			drive_id = i+1
			if drive_id < 10:
				#pad with a zero
				cmd_delete = "rm -f ./Coding/"+filename+"_k0" + str(drive_id)
			else:
				cmd_delete = "rm -f ./Coding/"+filename+"_k" + str(drive_id)
			os.system(cmd_delete)
	
		#delete coding drives
		for i in xrange(0,m_drives_to_delete):
			drive_id = i+1
			if drive_id < 10:
				#pad with a zero
				cmd_delete = "rm -f ./Coding/"+filename+"_m0" + str(drive_id)
			else:
				cmd_delete = "rm -f ./Coding/"+filename+"_m" + str(drive_id)
			os.system(cmd_delete)

		#decode
		cmd_decode = "./decoder " + filename
		print(cmd_decode)
		p = sub.Popen(cmd_decode,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
		output, errors = p.communicate()
		if errors != "":
			print("     " + errors)
	
		#see if the decoded file is the same as the original
		cmd_diff = "diff ./" + filename + " ./Coding/"+ filename + "_decoded"
		p = sub.Popen(cmd_diff,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
		output, errors = p.communicate()
		
		if output != "" or errors != "":
			print("Encode / decode failed")
			print(output)
			print(errors)
			num_failed+=1
		else:
			num_good+=1

		num_total+=1

		print("")

	print(str(num_good)+"/"+str(num_total) + " successful")

if __name__ == "__main__":
  main()

